#include "mydirectshow.h"
#include <QString>
#include <QDebug>

mydirectshow::mydirectshow(QObject *parent)
    : QObject{parent}
{
    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if (SUCCEEDED(hr))
    {
        IEnumMoniker *pEnum;

        hr = EnumerateDevices(CLSID_VideoInputDeviceCategory, &pEnum);
        if (SUCCEEDED(hr))
        {
            DisplayDeviceInformation(pEnum);
            pEnum->Release();
        }
//        hr = EnumerateDevices(CLSID_AudioInputDeviceCategory, &pEnum);
//        if (SUCCEEDED(hr))
//        {
//            DisplayDeviceInformation(pEnum);
//            pEnum->Release();
//        }
        CoUninitialize();
    } else {
        qDebug() << "CoInitializeEx return fail!";
    }
}

HRESULT mydirectshow::EnumerateDevices(REFGUID category, IEnumMoniker **ppEnum)
{
    // Create the System Device Enumerator.
    ICreateDevEnum *pDevEnum;
    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
        CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum));

    if (SUCCEEDED(hr))
    {
        // Create an enumerator for the category.
        hr = pDevEnum->CreateClassEnumerator(category, ppEnum, 0);
        if (hr == S_FALSE)
        {
            hr = VFW_E_NOT_FOUND;  // The category is empty. Treat as an error.
        }
        pDevEnum->Release();
    }
    return hr;
}

void mydirectshow::DisplayDeviceInformation(IEnumMoniker *pEnum)
{
    IMoniker *pMoniker = NULL;

    while (pEnum->Next(1, &pMoniker, NULL) == S_OK)
    {
        IPropertyBag *pPropBag;
        HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
        if (FAILED(hr))
        {
            pMoniker->Release();
            continue;
        }

        VARIANT var;
        VariantInit(&var);

        // Get description or friendly name.
        hr = pPropBag->Read(L"Description", &var, 0);
        if (FAILED(hr))
        {
            hr = pPropBag->Read(L"FriendlyName", &var, 0);
        }
        if (SUCCEEDED(hr))
        {
            char temp[255] = {0};
            for(int i = 0; i < 255; i++) {
                temp[i] = (char)var.bstrVal[i];
            }
            this->m_cameraNameList.append(QString(temp));
            qDebug() << "FriendlyName :" << QString(temp);
            VariantClear(&var);
        }

        hr = pPropBag->Write(L"FriendlyName", &var);

        // WaveInID applies only to audio capture devices.
        hr = pPropBag->Read(L"WaveInID", &var, 0);
        if (SUCCEEDED(hr))
        {
            qDebug() << "WaveIn ID:" << var.lVal;
            VariantClear(&var);
        }

        hr = pPropBag->Read(L"DevicePath", &var, 0);
        if (SUCCEEDED(hr))
        {
            // The device path is not intended for display.
            qDebug() << "Device path:" << var.bstrVal;
            VariantClear(&var);
        }

        pPropBag->Release();
        pMoniker->Release();
    }
}

QStringList mydirectshow::getCameraNameList()
{
    return this->m_cameraNameList;
}
